#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "yByteArray.h"
#include "../yCommon.h"
#include "yByteTools.h"

ByteArray::ByteArray() {
	wIndex = 0;
	rIndex = 0;
	capacity = 64;
	buf = (char*) malloc(capacity);
}

ByteArray::ByteArray(int c) {
	wIndex = 0;
	rIndex = 0;
	capacity = c;
	buf = (char*) malloc(capacity);
}
ByteArray::ByteArray(char* v, int len) {
	wIndex = len;
	rIndex = 0;
	capacity = len;
	buf = v;

}

ByteArray::~ByteArray() {
	free(buf);
}

int ByteArray::readByte() {
	assert(wIndex - rIndex >= 1);
	int value = read_byte(buf + rIndex);
	rIndex += 1;
	return value;
}

int ByteArray::readShort() {
	assert(wIndex - rIndex >= 2);
	int value = read_short(buf + rIndex);
	rIndex += 2;
	return value;
}

int ByteArray::readInt() {
	assert(wIndex - rIndex >= 4);
	int value = read_int(buf + rIndex);
	rIndex += 4;
	return value;
}

long ByteArray::readLong() {
	assert(wIndex - rIndex >= 8);
	long value = read_long(buf + rIndex);
	rIndex += 8;
	return value;
}

float ByteArray::readFloat() {
	assert(wIndex - rIndex >= 4);
	float value = read_float(buf + rIndex);
	rIndex += 4;
	return value;
}

double ByteArray::readDouble() {
	assert(wIndex - rIndex >= 8);
	double value = read_double(buf + rIndex);
	rIndex += 8;
	return value;
}

std::string ByteArray::readString() {
	int len = readShort();
	assert(wIndex - rIndex >= len);
	char* value = (char*) malloc(len + 1);
	memcpy(value, buf + rIndex, len);
	value[len] = '\0';
	rIndex += len;
	return std::string(value);
}

void ByteArray::writeByte(char value) {
	autoFitLen(1);
	write_byte(value, buf + wIndex);
	wIndex += 1;
}

void ByteArray::writeShort(short value) {
	autoFitLen(2);
	write_short(value, buf + wIndex);
	wIndex += 2;
}

void ByteArray::writeInt(int value) {
	autoFitLen(4);
	write_int(value, buf + wIndex);
	wIndex += 4;
}

void ByteArray::writeLong(long value) {
	autoFitLen(8);
	write_long(value, buf + wIndex);
	wIndex += 8;
}

void ByteArray::writeFloat(float value) {
	autoFitLen(4);
	write_float(value, buf + wIndex);
	wIndex += 4;
}

void ByteArray::writeDouble(double value) {
	autoFitLen(8);
	write_double(value, buf + wIndex);
	wIndex += 8;
}

void ByteArray::writeString(std::string &value) {
	int len = strlen(value.c_str());
	writeShort(len);
    char* str=const_cast<char*>(value.c_str());
	writeBytes(str, len);
}

void ByteArray::writeBytes(char* value, int len) {
	autoFitLen(len);
	memcpy(buf + wIndex, value, len);
	wIndex += len;
	free(value);
}

int ByteArray::readerIndex() {
	return rIndex;
}

int ByteArray::writerIndex() {
	return wIndex;
}

void ByteArray::readerIndex(int idx) {
	rIndex=idx;
}

void ByteArray::writerIndex(int idx) {
	wIndex=idx;
}

void ByteArray::autoFitLen(int len) {
	if (wIndex + len > capacity) {
		char *new_ptr = (char*) realloc(buf, capacity * 2);
		assert(new_ptr);
		buf = new_ptr;
		capacity *= 2;
	}
}
/*
 * yByteArray.cpp
 *
 *  Created on: Sep 14, 2016
 *      Author: root
 */

